package cn.itsource.blog.service.impl;

import cn.itsource.blog.domain. Community;
import cn.itsource.blog.mapper. CommunityMapper;
import cn.itsource.blog.query. CommunityQuery;

import cn.itsource.blog.service.ICommunityService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;

import javax.annotation.PostConstruct;
import java.util.*;

@Service
// Transactional：用来控制事务的注解；readOnly：只读；propagation：事务传播机制
//  Propagation.SUPPORTS：支持当前事务，如果没有当前事务，就以非事务方法执行
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public class CommunityServiceImpl implements ICommunityService {

    @Autowired
    private  CommunityMapper  communityMapper;


    @Transactional
    @Override
    public void add( Community  community) {
         communityMapper.add( community);
    }

    @Transactional
    @Override
    public void update( Community  community) {
         communityMapper.update( community);
    }

    @Transactional
    @Override
    public void delete(Long id) {
         communityMapper.delete(id);
    }

    @Override
    public  Community getOne(Long id) {
        return  communityMapper.getOne(id);
    }

    @Override
    public List< Community> getAll() {
        return  communityMapper.getAll();
    }

    @Transactional
    @Override
    public void patchDelete(Long[] ids) {
         communityMapper.patchDelete(ids);
    }

    @Override
    public PageInfo< Community> pageQuery(CommunityQuery query) {
        //原生的写法：1.先查询总页数  2.再根据分页的信息查询当前页的数据
        //PageHelper的写法：开启分页
//                PageHelper.startPage(当前页,每页显示的条数);
        PageHelper.startPage(query.getCurrentPage(), query.getPageSize());
        //分页查询：只要开启了分页，它会帮助我们做什么事情？
        //1.先查询总数量  //2.根据application.yml中驱动名自动实现分页，如果是mysql就用limit
        //3.自动计算limit的第一个值：limit a,b [a = 当前页的起始下标 = (当前页-1)*每页显示的条数]
//        List<Emp> emps = empMapper.pageQuery(empQuery);
        List< Community> list =  communityMapper.pageQuery(query);
        return new PageInfo(list);
    }

    @Autowired
    private RedisTemplate<String, String> redisTemplate; // 假设分数为Double类型

    @PostConstruct
//    // 使用@Scheduled注解定义定时任务，每一分钟执行一次
    /*秒（0-59）：表示每个小时的第几秒执行任务。
    分（0-59）：表示每个小时的第几分钟执行任务。
    时（0-23）：表示每天的第几小时执行任务。
    日（1-31）：表示月份中的哪一天执行任务。
    月（1-12 或 JAN-DEC）：表示哪个月份执行任务。
    星期几（1-7 或 SUN-SAT）：表示一周中的哪一天执行任务，这里的1代表星期日。
    但是，在Quartz Cron表达式中，日和星期几这两个字段是互斥的，这意味着你通常不会同时为它们设置值。为了解决这个问题，Quartz引入了一个特殊的字符?（问号），
    它可以用于日和星期几字段中的任意一个，表示“无特定值”。*/
//    @Scheduled(cron = "0 * * * * ?")

    // 使用@Scheduled注解定义定时任务，每小时执行一次
    @Scheduled(cron = "0 0 * * * ?")
    public void loadCommunityData() {
        List<Community> communityList = communityMapper.getAll();
        // 假设的社区数据
        String communityRanking = "community:ranking";
        // 使用ZADD命令将数据添加到Zset
        for (Community community : communityList) {
            redisTemplate.opsForZSet().add(communityRanking, community.getCommunityName(), community.getArticleCount()+community.getFansCount()*5);
        }
    }

    public List<ZSetOperations.TypedTuple<String>> CommunityRanking() {
        String zSetKey = "community:ranking"; // ZSET的key
// 使用reverseRangeWithScores获取分数最高的前十名成员及其分数
        Set<ZSetOperations.TypedTuple<String>> topCommunities = redisTemplate.opsForZSet().reverseRangeWithScores(zSetKey, 0, 9);
// 如果需要List而不是Set，可以转换为List
        return new ArrayList<>(topCommunities);
    }
    @Override
    public List<Community> getCommunityRanking(){
        ArrayList<Community> communityList = new ArrayList<>();
        List<ZSetOperations.TypedTuple<String>> list = CommunityRanking();
        List<Community> communityList1 = communityMapper.getAll();
        for (ZSetOperations.TypedTuple<String> stringTypedTuple : list) {
            String communityName = stringTypedTuple.getValue();
            for (Community community : communityList1) {
                if (communityName.equals(community.getCommunityName())){
                    communityList.add(community);
                }
            }
        }
        return communityList;
    }

   }
